home *** CD-ROM | disk | FTP | other *** search
/ Apple Developer Connection Student Program / ADC Tools Sampler CD Disk 3 1999.iso / Metrowerks CodeWarrior / Java Support / Java_Source / IFC_112 / netscape / application / RootView.java < prev    next >
Encoding:
Text File  |  1999-05-28  |  74.6 KB  |  2,376 lines  |  [TEXT/CWIE]

  1. // RootView.java
  2. // By Ned Etcode
  3. // Copyright 1995, 1996, 1997 Netscape Communications Corp.  All rights reserved.
  4.  
  5. package netscape.application;
  6.  
  7. import netscape.util.*;
  8.  
  9. /** View subclass that functions as the top level View of the Applet frame
  10.   * or ExternalWindow. It displays a Color and/or an Image (tiled, centered,
  11.   * or scaled). All other Applet Views and InternalWindows are descendants
  12.   * of the RootView.<p>You will rarely need to work with your
  13.   * Applet's RootView. You will never instantiate a RootView
  14.   * directly.
  15.   * @note 1.0 RootView now keep track of its focused view when a window become
  16.   * main when there is no longer any main window, the focus resume for the
  17.   * rootview focused view.
  18.   * @note 1.0 lots of changes drawing, keyboard UI, coordinate trns, menus
  19.   */
  20.  
  21. // ALERT! Need a boolean that says we're in mouse drag mode
  22. public class RootView extends View implements EventProcessor,
  23.     ExtendedTarget {
  24.     Color               _backgroundColor;
  25.     Image               _image;
  26.     FoundationPanel     panel;
  27.     Application         application;
  28.  
  29.     Timer               _autoscrollTimer;
  30.     ColorChooser        colorChooser;
  31.     FontChooser         fontChooser;
  32.     InternalWindow      _mainWindow;
  33.     View                _mouseView, _moveView, _focusedView, _windowClipView,
  34.                         _mouseClickView,_rootViewFocusedView;
  35.                         /* Warning always use rootViewFocusedView()
  36.                            to access this ivar */
  37.     View                _selectedView; /* Selected view for keyboard UI */
  38.     View                _defaultSelectedView;
  39.     Vector              windows = new Vector();
  40.     long                _lastClickTime;
  41.     int                 _clickCount, _mouseX, _mouseY, _currentCursor,
  42.                         _viewCursor, _overrideCursor = DEFAULT_CURSOR,
  43.                         mouseDownCount, _imageDisplayStyle;
  44.     Vector              dirtyViews = new Vector();
  45.     boolean             _redrawTransWindows = true, recomputeCursor,
  46.                         recomputeMoveView, isVisible, redrawAll = true;
  47.     Vector              componentViews;
  48.     MouseFilter         mouseFilter = new MouseFilter();
  49.  
  50.     static Vector _commands;
  51.  
  52.     static final String VALIDATE_SELECTED_VIEW = "validateSelectedView";
  53.  
  54.     static {
  55.         _commands = new Vector();
  56.         _commands.addElement(SHOW_FONT_CHOOSER);
  57.         _commands.addElement(SHOW_COLOR_CHOOSER);
  58.         _commands.addElement(NEW_FONT_SELECTION);
  59.         _commands.addElement(VALIDATE_SELECTED_VIEW);
  60.     }
  61.  
  62.     /* constructors */
  63.  
  64.     /** Constructs a RootView with origin <B>(0, 0)</b> and zero
  65.       * width and height.
  66.       */
  67.     public RootView() {
  68.         this(0, 0, 0, 0);
  69.     }
  70.  
  71.     /** Constructs a RootView with bounds <B>rect</B>.
  72.       */
  73.     public RootView(Rect rect) {
  74.         this(rect.x, rect.y, rect.width, rect.height);
  75.     }
  76.  
  77.     /** Constructs a RootView with
  78.       * bounds (<B>x</B>, <B>y</B>, <B>width</B>, <B>height</B>)
  79.       */
  80.     public RootView(int x, int y, int width, int height) {
  81.         super(x, y, width, height);
  82.  
  83.         _backgroundColor = Color.gray;
  84.         application = Application.application();
  85.         _defaultSelectedView = this;
  86.     }
  87.  
  88.     /* window management */
  89.  
  90.     void addWindowRelativeTo(InternalWindow aWindow, int position,
  91.                              InternalWindow otherWindow) {
  92.         if (aWindow == null) {
  93.             return;
  94.         }
  95.  
  96.         if (_windowClipView != null && aWindow.layer() < InternalWindow.IGNORE_WINDOW_CLIPVIEW_LAYER) {
  97.             _windowClipView.addSubview(aWindow);
  98.         } else {
  99.             addSubview(aWindow);
  100.         }
  101.  
  102.         makeWindowVisible(aWindow, position, otherWindow);
  103.     }
  104.  
  105.     void removeWindow(InternalWindow aWindow) {
  106.         InternalWindow  newMain, theWindow;
  107.         int             index,count;
  108.         Rect windowBounds;
  109.  
  110.         if (aWindow == null) {
  111.             return;
  112.         }
  113.  
  114.         windowBounds = absoluteWindowBounds(aWindow);
  115.  
  116.         aWindow.removeFromSuperview();
  117.  
  118.         index = windows.indexOf(aWindow) - 1;
  119.         if (index < 0) {
  120.             index = windows.indexOf(aWindow);
  121.         }
  122.  
  123.         windows.removeElement(aWindow);
  124.         if (aWindow == _mainWindow) {
  125.             theWindow = null;
  126.             for(index = windows.count() - 1 ; index >= 0 ; index--) {
  127.                 if(((InternalWindow)windows.elementAt(index)).canBecomeMain()) {
  128.                     theWindow = (InternalWindow)windows.elementAt(index);
  129.                     break;
  130.                 }
  131.             }
  132.             _setMainWindow(theWindow);
  133.         }
  134.  
  135.         if(canDraw()) {
  136.         redraw(windowBounds);
  137.         redrawTransparentWindows(windowBounds, null);
  138.         }
  139.  
  140.         if(!(aWindow  instanceof KeyboardArrow))
  141.             validateSelectedView();
  142.         createMouseEnterLater();
  143.     }
  144.  
  145.     /** Returns the Vector containing all InternalWindows currently displayed
  146.       * in the RootView.  Do <i>not</i> modify this Vector.
  147.      */
  148.     public Vector internalWindows() {
  149.         return windows;
  150.     }
  151.  
  152.     /** Returns the Application's main InternalWindow.  The main InternalWindow
  153.       * represents the InternalWindow the user is currently working with, and
  154.       * displays its title bar differently than all other InternalWindows.  The
  155.       * IFC passes key Events to the View in the main InternalWindow that has
  156.       * requested to receive them.
  157.       * @see InternalWindow
  158.       */
  159.     public InternalWindow mainWindow() {
  160.         return _mainWindow;
  161.     }
  162.  
  163.     void _setMainWindow(InternalWindow newMain) {
  164.         InternalWindow      oldMain,nextWindow;
  165.  
  166.         if ((_mainWindow == newMain) ||
  167.             (newMain != null && !newMain.canBecomeMain())) {
  168.             return;
  169.         }
  170.  
  171.         oldMain = _mainWindow;
  172.         _mainWindow = newMain;
  173.  
  174.         if (oldMain != null) {
  175.             oldMain.didResignMain();
  176.         } else if(_focusedView != null && !isInWindow(_focusedView)) {
  177.             _rootViewFocusedView = _focusedView;
  178.             setFocusedView(null,false);
  179.         }
  180.  
  181.  
  182.         if (_mainWindow != null) {
  183.             _mainWindow.didBecomeMain();
  184.         } else if(rootViewFocusedView() != null) {
  185.             setFocusedView(rootViewFocusedView(),false);
  186.             _rootViewFocusedView = null;
  187.         }
  188.         validateSelectedView();
  189.         createMouseEnterLater();
  190.     }
  191.  
  192.     InternalWindow frontWindowWithLayer(int aLayer) {
  193.         int i;
  194.         InternalWindow win;
  195.  
  196.         for(i = windows.count()-1; i >= 0 ; i--) {
  197.             win = (InternalWindow)windows.elementAt(i);
  198.             if(win.layer() == aLayer)
  199.                 return win;
  200.         }
  201.         return null;
  202.     }
  203.  
  204.     InternalWindow backWindowWithLayer(int aLayer) {
  205.         int i,c = windows.count();
  206.         InternalWindow win;
  207.  
  208.         for(i=0; i<c ; i++) {
  209.             win = (InternalWindow)windows.elementAt(i);
  210.             if(win.layer() == aLayer)
  211.                 return win;
  212.         }
  213.         return null;
  214.     }
  215.  
  216.     void makeWindowVisible(InternalWindow aWindow, int position,
  217.                            InternalWindow otherWindow) {
  218.         InternalWindow          nextWindow = null;
  219.         int             originalIndex, windowLayer, i;
  220.         boolean         found, redrawWindow, inserted;
  221.  
  222.         if (aWindow == null) {
  223.             return;
  224.         }
  225.  
  226.         /** If the window is not in this view hierarchy
  227.          *  it it impossible to move it to the front
  228.          */
  229.         if(!aWindow.descendsFrom(this))
  230.             return;
  231.  
  232.         originalIndex = windows.indexOf(aWindow);
  233.         windowLayer = aWindow.layer();
  234.  
  235.       /* make sure relative window is in the same layer */
  236.         if (otherWindow != null) {
  237.             if (otherWindow.layer() > windowLayer) {
  238.                 otherWindow = null;
  239.                 position = InternalWindow.ABOVE;
  240.             } else if (otherWindow.layer() < windowLayer) {
  241.                 otherWindow = null;
  242.                 position = InternalWindow.BEHIND;
  243.             }
  244.         }
  245.  
  246.         windows.removeElement(aWindow);
  247.  
  248.         if (otherWindow != null) {
  249.             if (position == InternalWindow.ABOVE) {
  250.                 found = windows.insertElementAfter(aWindow, otherWindow);
  251.             } else {
  252.                 found = windows.insertElementBefore(aWindow, otherWindow);
  253.             }
  254.  
  255.             if (found) {
  256.                 _setMainWindow(aWindow);
  257.  
  258.                 if (originalIndex != windows.indexOf(aWindow)) {
  259.                     aWindow.draw();
  260.                     updateTransWindows(aWindow);
  261.                     if(position == InternalWindow.BEHIND) {
  262.                         updateWindowsAbove(aWindow);
  263.                     }
  264.                 }
  265.                 return;
  266.             }
  267.  
  268.           /* otherWindow not in window list, so just ignore */
  269.             otherWindow = null;
  270.         }
  271.  
  272.       /* make first window in our layer */
  273.         i = windows.count();
  274.         while (i-- > 0) {
  275.             nextWindow = (InternalWindow)windows.elementAt(i);
  276.  
  277.             if (nextWindow.layer() > windowLayer) {
  278.                 continue;
  279.             } else if (nextWindow.layer() <= windowLayer) {
  280.                 break;
  281.             }
  282.         }
  283.  
  284.         if (nextWindow == null) {
  285.             windows.insertElementAt(aWindow, 0);
  286.             inserted = true;
  287.         } else if (nextWindow.layer() > windowLayer) {
  288.             inserted = windows.insertElementBefore(aWindow, nextWindow);
  289.         } else {
  290.             inserted = windows.insertElementAfter(aWindow, nextWindow);
  291.         }
  292.         if (!inserted) {
  293.             windows.insertElementAt(aWindow, 0);
  294.         }
  295.  
  296.         _setMainWindow(aWindow);
  297.  
  298.         if (originalIndex != windows.indexOf(aWindow)) {
  299.             aWindow.draw();
  300.             updateTransWindows(aWindow);
  301.         }
  302.     }
  303.  
  304.  
  305.     void updateWindowsAbove(InternalWindow aWindow) {
  306.         InternalWindow win;
  307.         int i,c,index;
  308.         Rect windowBounds = absoluteWindowBounds(aWindow);
  309.         Rect  winBounds;
  310.         index = windows.indexOf(aWindow);
  311.         Rect  inter = new Rect();
  312.  
  313.         for(i=index+1,c=windows.count() ; i < c ;i++) {
  314.             win = (InternalWindow) windows.elementAt(i);
  315.             winBounds = absoluteWindowBounds(win);
  316.             if(windowBounds.intersects(winBounds)) {
  317.                 inter.setBounds(windowBounds);
  318.                 inter.intersectWith(winBounds);
  319.                 convertRectToView(win,inter,inter);
  320.                 win.addDirtyRect(inter);
  321.             }
  322.         }
  323.     }
  324.  
  325.     void updateTransWindows(InternalWindow belowWindow) {
  326.         InternalWindow          nextWindow;
  327.         Rect            belowRect;
  328.         int             i, count;
  329.  
  330.         if (belowWindow == null) {
  331.             return;
  332.         }
  333.  
  334.         /// ALERT FIX 3
  335.         count = windows.indexOf(belowWindow);
  336.         belowRect = belowWindow.superview().convertRectToView(this, belowWindow.bounds);
  337. //        belowRect = belowWindow.bounds;
  338.         for (i = 0; i < count; i++) {
  339.             Rect windowBounds;
  340.             nextWindow = (InternalWindow)windows.elementAt(i);
  341.  
  342.             if (!nextWindow.isTransparent()) {
  343.                 continue;
  344.             }
  345.             windowBounds = absoluteWindowBounds(nextWindow);
  346.  
  347.             if (windowBounds.intersects(belowRect) ||
  348.                 belowRect.intersects(windowBounds)) {
  349.  
  350.                 nextWindow.updateDrawingBuffer();
  351.             }
  352.         }
  353.     }
  354.  
  355.  
  356.   /* drawing */
  357.  
  358.     void disableWindowsAbove(InternalWindow aWindow, boolean flag) {
  359.         InternalWindow  nextWindow;
  360.         int     i, count;
  361.  
  362.         if (aWindow == null) {
  363.             return;
  364.         }
  365.  
  366.         i = windows.indexOf(aWindow);
  367.  
  368.         if (i == -1) {
  369.             return;
  370.         }
  371.  
  372.         count = windows.count();
  373.         for (; i < count; i++) {
  374.             nextWindow = (InternalWindow)windows.elementAt(i);
  375.             if (flag) {
  376.                 nextWindow.disableDrawing();
  377.             } else {
  378.                 nextWindow.reenableDrawing();
  379.             }
  380.         }
  381.     }
  382.  
  383.     Vector windowRects(Rect aRect, InternalWindow viewWindow) {
  384.         InternalWindow    nextWindow;
  385.         Vector            rectVector = null;
  386.         int               i, count;
  387.  
  388.         count = windows.count();
  389.         if (viewWindow != null) {
  390.             i = windows.indexOf(viewWindow) + 1;
  391.         } else {
  392.             i = 0;
  393.         }
  394.         for (; i < count; i++) {
  395.             /// ALERT FIX 4 - THIS IS A BIG ONE
  396.             Rect windowBounds;
  397.             nextWindow = (InternalWindow)windows.elementAt(i);
  398.  
  399.             windowBounds = absoluteWindowBounds(nextWindow);
  400.  
  401.             if (windowBounds.intersects(aRect) ||
  402.                 aRect.intersects(windowBounds)) {
  403.                 if (rectVector == null) {
  404.                     rectVector = VectorCache.newVector();
  405.                 }
  406.                 rectVector.addElement(new Rect(windowBounds));
  407.             }
  408.         }
  409.  
  410.         return rectVector;
  411.     }
  412.  
  413.     void setRedrawTransparentWindows(boolean flag) {
  414.         _redrawTransWindows = flag;
  415.     }
  416.  
  417.     /** @private
  418.       */
  419.     public void redrawTransparentWindows(Rect clipRect,
  420.                                          InternalWindow aboveWindow) {
  421.         redrawTransparentWindows(null, clipRect, aboveWindow);
  422.     }
  423.  
  424.     /** @private
  425.       */
  426.     public void redrawTransparentWindows(Graphics g,
  427.                                          Rect clipRect,
  428.                                          InternalWindow aboveWindow) {
  429.         InternalWindow  nextWindow;
  430.         int             i, count;
  431.         Rect            windowRect = null;
  432.  
  433.         if (!_redrawTransWindows) {
  434.             return;
  435.         }
  436. /// ALERT!
  437. /// THIS WAS PUT IN TO HANDLE THE CASE IN CONSTRUCTOR WHERE
  438. /// BORDERED POPUP WAS SETTING THE BORDER IN IT'S DRAW METHOD WHICH FORCED A
  439. /// DRAW() TO GET CALLED AND WE INFINITE RECURSED.
  440. /// BUT THIS FIXED CAUSED TRANSPARENT INTERNAL WINDOWS NOT TO DRAW PROPERLY WHEN
  441. /// THINGS BEHIND THEM MOVED.
  442. //        _redrawTransWindows = false;
  443.         count = windows.count();
  444.         if (aboveWindow != null) {
  445.             i = windows.indexOf(aboveWindow) + 1;
  446.         } else {
  447.             i = 0;
  448.         }
  449.         for (; i < count; i++) {
  450.             /// ALERT FIX 5
  451.             Rect windowBounds;
  452.             nextWindow = (InternalWindow)windows.elementAt(i);
  453.  
  454.             if (!nextWindow.isTransparent()) {
  455.                 continue;
  456.             }
  457.  
  458.             windowBounds = absoluteWindowBounds(nextWindow);
  459.             if (windowBounds.intersects(clipRect)) {
  460.  
  461.                 if (windowRect == null)
  462.                     windowRect = Rect.newRect();
  463.  
  464.                 convertRectToView(nextWindow, clipRect, windowRect);
  465.  
  466.                 nextWindow.draw(g, windowRect);
  467.             }
  468.         }
  469.         if (windowRect != null) {
  470.             Rect.returnRect(windowRect);
  471.         }
  472. //        _redrawTransWindows = true;
  473.     }
  474.  
  475.      void paint(ApplicationEvent updateEvent) {
  476.         UpdateFilter updateFilter = new UpdateFilter(updateEvent.rect());
  477.         int i;
  478.  
  479.         updateFilter.rootView = this;
  480.  
  481.         try {
  482.             Thread.sleep(100);
  483.         } catch (InterruptedException e) {
  484.         }
  485.  
  486.         application.eventLoop().filterEvents(updateFilter);
  487.  
  488.         if (redrawAll) {
  489.             // We are redrawing the entire RootView because on Windows
  490.             // there is a bug which causes the wrong clipRect to be given.
  491.             Rect clipRect = Rect.newRect(0, 0, bounds.width, bounds.height);
  492.  
  493.             redraw(clipRect);
  494.             redrawTransparentWindows(clipRect, null);
  495.             Rect.returnRect(clipRect);
  496.         } else {
  497.             redraw(updateFilter._rect);
  498.             redrawTransparentWindows(updateFilter._rect, null);
  499.         }
  500.  
  501.         /* jla - this was needed to get repaint events to flush properly in
  502.          * navigator on solaris
  503.          */
  504.         AWTCompatibility.awtToolkit().sync();
  505.     }
  506.  
  507.     void print(ApplicationEvent printEvent) {
  508.         Rect rect = new Rect(0, 0, width(), height());
  509.         Graphics ifcGraphics = new Graphics(rect, printEvent.graphics());
  510.  
  511.         redraw(ifcGraphics, rect);
  512.         redrawTransparentWindows(ifcGraphics, rect, null);
  513.     }
  514.  
  515.     void resize(ApplicationEvent resizeEvent) {
  516.         ResizeFilter resizeFilter = new ResizeFilter();
  517.  
  518.         try {
  519.             Thread.sleep(50);
  520.         } catch (InterruptedException e) {
  521.         }
  522.         resizeFilter.lastEvent = resizeEvent;
  523.         application.eventLoop().filterEvents(resizeFilter);
  524.  
  525.         sizeTo(resizeFilter.lastEvent.rect().width,
  526.                resizeFilter.lastEvent.rect().height);
  527.     }
  528.  
  529. /* events */
  530.  
  531.     /** If called after a MOUSE_DOWN or MOUSE_DRAGGED Event, forces all
  532.       * subsequent MOUSE_DRAGGED Events and the MOUSE_UP Event to go to
  533.       * <b>aView</b>.
  534.       */
  535.     public void setMouseView(View aView) {
  536.         _mouseView = aView;
  537.     }
  538.  
  539.     /** Returns the View currently receiving MOUSE_DRAGGED or MOUSE_UP Events.
  540.       * @see #setMouseView
  541.       */
  542.     public View mouseView() {
  543.         return _mouseView;
  544.     }
  545.  
  546.  
  547.     /** Returns the View under point (<b>x</b>, <b>y</b>).
  548.      */
  549.     public View viewForMouse(int x, int y) {
  550.         InternalWindow  nextWindow;
  551.         View    theView = null;
  552.         int     i;
  553.  
  554.         i = windows.count();
  555.         while (i-- > 0 && theView == null) {
  556.             // ALERT FIX 2
  557.             Rect windowBounds;
  558.             nextWindow = (InternalWindow)windows.elementAt(i);
  559.             windowBounds = absoluteWindowBounds(nextWindow);
  560.             theView = nextWindow.viewForMouse(x - windowBounds.x,
  561.                                               y - windowBounds.y);
  562.         }
  563.  
  564.         if (theView != null)
  565.             return theView;
  566.         else
  567.             return super.viewForMouse(x, y);
  568.     }
  569.  
  570.     void _mouseDown(MouseEvent event) {
  571.         InternalWindow  mouseWindow;
  572.         View            newMouseView, origMouseView, modalView;
  573.         long            currentTime;
  574.  
  575.         mouseDownCount++;
  576.  
  577.         /* if one mouse button is already down, filter out additional downs */
  578.         if (mouseDownCount > 1) {
  579.             return;
  580.         }
  581.  
  582.         /* who got clicked */
  583.         newMouseView = viewForMouse(event.x, event.y);
  584.         if (newMouseView == null) {
  585.             _mouseView = null;
  586.             return;
  587.         }
  588.  
  589.         /* have to compare new view to current to determine if there's really
  590.          * a double-click
  591.          */
  592.         // click count is now kept by the awt.  ALERT!
  593.         currentTime = event.timeStamp;
  594.         if (_mouseClickView == newMouseView &&
  595.             (currentTime - _lastClickTime < 250)) {
  596.             _clickCount++;
  597.         } else {
  598.             _clickCount = 1;
  599.         }
  600.         _lastClickTime = currentTime;
  601.         event.setClickCount(_clickCount);
  602.  
  603.         /* we set this even if we're in a modal loop because subsequent mouse
  604.          * moved events will be meant for the clicked view;  if it isn't the
  605.          * same as the modal view or descendant, we'll just filter it at
  606.          * that point
  607.          */
  608.         _mouseView = _mouseClickView = newMouseView;
  609.  
  610.         if (viewExcludedFromModalSession(newMouseView))
  611.             return;
  612.  
  613.         /* set the _mouseView's window's active view */
  614.         if (!(_mouseView instanceof InternalWindow)) {
  615.             mouseWindow = _mouseView.window();
  616.             if (!(_mouseView instanceof MenuView) || (mouseWindow != null)) {
  617.                 _setMainWindow(mouseWindow);
  618.             }
  619.         }
  620.  
  621.         /* pass the event along */
  622.         event.x -= _mouseView.absoluteX();
  623.         event.y -= _mouseView.absoluteY();
  624.  
  625.         /* inside of mouse down, the program might set the mouse view to be
  626.          * some other view;  if mouseDown() returns false and we don't check
  627.          * for this, the new mouse view will not receive more mouse events
  628.          */
  629.         origMouseView = _mouseView;
  630.  
  631.         if (!_mouseView.mouseDown(event) && (origMouseView == _mouseView)) {
  632.             _mouseView = null;
  633.         }
  634.     }
  635.  
  636.     /** Returns <b>true</b> if the RootView is visible. */
  637.     public boolean isVisible() {
  638.         return isVisible;
  639.     }
  640.  
  641.     void setVisible(boolean flag) {
  642.         if (isVisible != flag) {
  643.             isVisible = flag;
  644.             if (isVisible) {
  645.                 ancestorWasAddedToViewHierarchy(this);
  646.                 if (_focusedView != null) {
  647.                     _focusedView._startFocus();
  648.                     Application.application().focusChanged(_focusedView);
  649.                 }
  650.             } else {
  651.                 ancestorWillRemoveFromViewHierarchy(this);
  652.                 if (_focusedView != null) {
  653.                     _focusedView._pauseFocus();
  654.                 }
  655.             }
  656.         }
  657.     }
  658.  
  659.     void _mouseDrag(MouseEvent event) {
  660.         Autoscroller    autoscroller;
  661.         boolean         pointIsVisible;
  662.  
  663.         /* modal loop? */
  664.         if(viewExcludedFromModalSession(_mouseView))
  665.             return;
  666.  
  667.         if (_mouseView != null) {
  668.             pointIsVisible =
  669.                 _mouseView.containsPointInVisibleRect(event.x, event.y);
  670.  
  671.             if (_mouseView.wantsAutoscrollEvents() && !pointIsVisible) {
  672.                 if (_autoscrollTimer == null) {
  673.                     autoscroller = new Autoscroller();
  674.  
  675.                     _autoscrollTimer = new Timer(autoscroller, "autoscroll",
  676.                                                  100);
  677.                     _autoscrollTimer.start();
  678.                     _autoscrollTimer.setData(_mouseView);
  679.                     autoscroller.setEvent(
  680.                                 _mouseView.convertEventToView(null, event));
  681.                 } else {
  682.                     autoscroller = (Autoscroller)_autoscrollTimer.target();
  683.                     autoscroller.setEvent(
  684.                                 _mouseView.convertEventToView(null, event));
  685.                 }
  686.             } else {
  687.                 if (_autoscrollTimer != null) {
  688.                     _autoscrollTimer.stop();
  689.                     _autoscrollTimer = null;
  690.                 }
  691.                 event.setClickCount(_clickCount);
  692.  
  693.                 _mouseView.mouseDragged(event);
  694.             }
  695.         } else if (_autoscrollTimer != null) {
  696.             _autoscrollTimer.stop();
  697.             _autoscrollTimer = null;
  698.         }
  699.     }
  700.  
  701.     void _mouseUp(MouseEvent event) {
  702.         View newMoveView;
  703.  
  704.         mouseDownCount--;
  705.  
  706.         /* if mouse still down (multiple mouse buttons) filter out the up */
  707.         if (mouseDownCount > 0) {
  708.             return;
  709.         }
  710.  
  711.         /* modal loop? */
  712.         if(viewExcludedFromModalSession(_mouseView)) {
  713.             return;
  714.         }
  715.  
  716.         if (_mouseView != null) {
  717.             event.setClickCount(_clickCount);
  718.             _mouseView.mouseUp(event);
  719.  
  720.             if (_autoscrollTimer != null) {
  721.                 _autoscrollTimer.stop();
  722.                 _autoscrollTimer = null;
  723.             }
  724.         }
  725.         /* if released outside of move view, need to generate
  726.          * a mouse move event
  727.          */
  728.         newMoveView = viewForMouse(_mouseX, _mouseY);
  729.         if (newMoveView != _moveView) {
  730.             createMouseEnter();
  731.         }
  732.         _mouseClickView = _mouseView;
  733.         _mouseView = null;
  734.     }
  735.  
  736.     void createMouseEnter() {
  737.         MouseEvent        fakeMouseEvent;
  738.  
  739.         fakeMouseEvent = new MouseEvent(System.currentTimeMillis(),
  740.                                         MouseEvent.MOUSE_ENTERED, _mouseX,
  741.                                         _mouseY, 0);
  742.         _mouseEnter(fakeMouseEvent);
  743.     }
  744.  
  745.     void createMouseEnterLater() {
  746.         if (_mouseView == null) {
  747.             recomputeMoveView = true;
  748.         }
  749.     }
  750.  
  751.     void _mouseEnter(MouseEvent event) {
  752.         _mouseMove(event);
  753.     }
  754.  
  755.     void _mouseMove(MouseEvent event) {
  756.         View            newMoveView, oldMoveView;
  757.  
  758.         newMoveView = viewForMouse(event.x, event.y);
  759.  
  760.         /** When we have a modal view, we should send mouse moved events
  761.          *  only to view that are descendant from the modal view
  762.          */
  763.         if(viewExcludedFromModalSession(newMoveView))
  764.             return;
  765.  
  766.         if (newMoveView == _moveView) {
  767.             MouseEvent cEvent;
  768.             if (_moveView == null) {
  769.                 return;
  770.             }
  771.  
  772.             cEvent = convertEventToView(_moveView,event);
  773.  
  774.             _moveView.mouseMoved(cEvent);
  775.         } else {
  776.             oldMoveView = _moveView;
  777.             _moveView = newMoveView;
  778.             if (oldMoveView != null) {
  779.                 MouseEvent e = convertEventToView(oldMoveView, event);
  780.                 e.setType(MouseEvent.MOUSE_EXITED);
  781.                 oldMoveView.mouseExited(e);
  782.             }
  783.  
  784.             if (_moveView != null) {
  785.                 MouseEvent e = convertEventToView(_moveView, event);
  786.                 e.setType(MouseEvent.MOUSE_ENTERED);
  787.                 _moveView.mouseEntered(e);
  788.             }
  789.         }
  790.  
  791.         updateCursorLater();
  792.     }
  793.  
  794.     void _mouseExit(MouseEvent event) {
  795.         if (_moveView != null) {
  796.             _moveView.mouseExited(convertEventToView(_moveView, event));
  797.             _moveView = null;
  798.  
  799.             updateCursorLater();
  800.         }
  801.     }
  802.  
  803.  
  804.  
  805. /* cursors */
  806.  
  807.  
  808.     void flushCursor() {
  809.         int        cursorToSet;
  810.  
  811.         if (_overrideCursor != DEFAULT_CURSOR) {
  812.             cursorToSet = _overrideCursor;
  813.         } else {
  814.             cursorToSet = _viewCursor;
  815.         }
  816.  
  817.         if (cursorToSet != _currentCursor) {
  818.             panel.setCursor(cursorToSet);
  819.             _currentCursor = cursorToSet;
  820.         }
  821.     }
  822.  
  823.     void computeCursor() {
  824.         View        underView;
  825.         Point        mousePoint;
  826.  
  827.         underView = viewForMouse(_mouseX, _mouseY);
  828.         if (underView != null) {
  829.             mousePoint = Point.newPoint();
  830.             convertToView(underView, _mouseX, _mouseY, mousePoint);
  831.  
  832.             _viewCursor = underView.cursorForPoint(mousePoint.x, mousePoint.y);
  833.  
  834.             Point.returnPoint(mousePoint);
  835.         } else {
  836.             _viewCursor = ARROW_CURSOR;
  837.         }
  838.  
  839.         flushCursor();
  840.     }
  841.  
  842.     /** Returns the current cursor.
  843.       * @see View#cursorForPoint
  844.       * @see #setOverrideCursor
  845.       */
  846.     public int cursor() {
  847.         return _currentCursor;
  848.     }
  849.  
  850.     /** Forces the RootView's currently displayed cursor to the cursor
  851.       * identified by <b>cursorIdent</b>, regardless of the cursor requested by
  852.       * the View currently under the mouse.  To return the cursor to what it
  853.       * should be, call <b>removeOverrideCursor()</b>.<p>
  854.       * You will almost never call this method - instead, your View subclasses
  855.       * will override their <b>cursorForPoint()</b> method to return the
  856.       * correct cursor for that point within the View.
  857.       * @see View#cursorForPoint
  858.       * @see #removeOverrideCursor
  859.       */
  860.      public void setOverrideCursor(int cursorIdent) {
  861.         if (cursorIdent < DEFAULT_CURSOR || cursorIdent > MOVE_CURSOR) {
  862.             throw new InconsistencyException("Unknown cursor type: " +
  863.                                              cursorIdent);
  864.         }
  865.  
  866.         if (_overrideCursor != cursorIdent) {
  867.             _overrideCursor = cursorIdent;
  868.             flushCursor();
  869.         }
  870.     }
  871.  
  872.     /** Removes the override cursor, returning the cursor to the cursor
  873.       * requested by the View currently under the mouse.
  874.       * @see #setOverrideCursor
  875.       */
  876.     public void removeOverrideCursor() {
  877.         setOverrideCursor(DEFAULT_CURSOR);
  878.     }
  879.  
  880.     /** Forces the RootView to immediately compute and set the cursor
  881.       * based on the View under the mouse.
  882.       */
  883.     public void updateCursor() {
  884.         computeCursor();
  885.     }
  886.  
  887.     /** Forces the RootView to recompute the current cursor upon
  888.       * reaching the top of the EventLoop.
  889.       */
  890.     public void updateCursorLater() {
  891.         recomputeCursor = true;
  892.     }
  893.  
  894.     void _updateCursorAndMoveView() {
  895.         if (recomputeMoveView) {
  896.             createMouseEnter();
  897.             recomputeMoveView = false;
  898.             recomputeCursor = false;
  899.         } else if (recomputeCursor) {
  900.             computeCursor();
  901.             recomputeCursor = false;
  902.         }
  903.     }
  904.  
  905.  
  906.  
  907. /* mouse events */
  908.  
  909.  
  910.     void _keyDown(KeyEvent event) {
  911.         View            keyView;
  912.         ExternalWindow  externalWindow;
  913.         boolean         eventHandled = false;
  914.         MenuItem        item = null;
  915.  
  916.         keyView = _focusedView;
  917.         externalWindow = externalWindow();
  918.  
  919.         // ALERT.  This is only for AWT Menus.
  920.         if (externalWindow != null) {
  921.             if (externalWindow.menu() != null) {
  922.                 if (JDK11AirLock.menuShortcutExists()) {
  923.                     // ALERT.  JDK 1.1.1 native Menus with MenuShortcuts
  924.                     // perform the associated MenuItem's command,
  925.                     // and also call keyDown after, so we need to make sure
  926.                     // the event is not handled twice.  We check to see
  927.                     // if one of the MenuItems would have presumably
  928.                     // already handled the Event by seeing if any MenuItems
  929.                     // have the corresponding command key-equivalent.
  930.                     item = externalWindow.menu().itemForKeyEvent(event);
  931.                     if (item != null) {
  932.                         eventHandled = true;
  933.                     }
  934.                 } else {
  935.                     eventHandled = externalWindow.menu().handleCommandKeyEvent(event);
  936.                 }
  937.             }
  938.         }
  939.         if (!eventHandled) {
  940.             if(processKeyboardEvent(event,true))
  941.                 return;
  942.             if (keyView != null && !viewExcludedFromModalSession(keyView)) {
  943.                 keyView.keyDown(event);
  944.             } else {
  945.                 application().keyDown(event);
  946.             }
  947.         }
  948.     }
  949.  
  950.     void _keyUp(KeyEvent event) {
  951.         View    keyView;
  952.  
  953.         keyView = _focusedView;
  954.  
  955.         if (keyView != null && !viewExcludedFromModalSession(keyView)) {
  956.             keyView.keyUp(event);
  957.         } else {
  958.             application().keyUp(event);
  959.         }
  960.     }
  961.  
  962.     void _keyTyped(KeyEvent event) {
  963.       View    keyView;
  964.  
  965.       keyView = _focusedView;
  966.  
  967.       if (keyView != null && !viewExcludedFromModalSession(keyView)) {
  968.         keyView.keyTyped(event);
  969.       } else {
  970.         application().keyTyped(event);
  971.       }
  972.     }
  973.  
  974. /* panels */
  975.  
  976.     /** Makes the ColorChooser visible.
  977.       * @see ColorChooser
  978.       */
  979.     public void showColorChooser() {
  980.         colorChooser().show();
  981.     }
  982.  
  983.     /** Returns a reference to the shared ColorChooser.
  984.       * @see ColorChooser
  985.       */
  986.     public ColorChooser colorChooser() {
  987.         if (colorChooser == null) {
  988.             InternalWindow window = new InternalWindow(0, 0, 10, 10);
  989.  
  990.             window.setRootView(this);
  991.             colorChooser = new ColorChooser();
  992.             colorChooser.setWindow(window);
  993.             window.center();
  994.         }
  995.         return colorChooser;
  996.     }
  997.  
  998.     /** Makes the FontChooser visible.
  999.      * @see FontChooser
  1000.      */
  1001.     public void showFontChooser() {
  1002.         fontChooser().show();
  1003.     }
  1004.  
  1005.     /** Returns a reference to the shared FontChooser.
  1006.       * @see FontChooser
  1007.       */
  1008.     public FontChooser fontChooser() {
  1009.         if (fontChooser == null) {
  1010.             InternalWindow fontWindow = new InternalWindow(0, 0, 1, 1);
  1011.  
  1012.             fontWindow.setRootView(this);
  1013.             fontChooser = new FontChooser();
  1014.             fontChooser.setWindow(fontWindow);
  1015.             fontWindow.center();
  1016.         }
  1017.  
  1018.         return fontChooser;
  1019.     }
  1020.  
  1021.     /** Returns the RootView's ExternalWindow, if any.
  1022.       */
  1023.     public ExternalWindow externalWindow() {
  1024.         java.awt.Component component;
  1025.  
  1026.         for (component = panel;
  1027.              component != null;
  1028.              component = component.getParent()) {
  1029.             if (component instanceof FoundationFrame)
  1030.                 return ((FoundationFrame) component).externalWindow;
  1031.             else if(component instanceof FoundationDialog)
  1032.                 return ((FoundationDialog) component).externalWindow;
  1033.             else if(component instanceof FoundationWindow)
  1034.                 return ((FoundationWindow) component).externalWindow;
  1035.         }
  1036.         return null;
  1037.     }
  1038.  
  1039.   /* running */
  1040.  
  1041.     MouseEvent removeMouseEvents(MouseEvent mouseEvent) {
  1042.         MouseEvent newEvent;
  1043.  
  1044.         newEvent = (MouseEvent)application.eventLoop().filterEvents(mouseFilter);
  1045.  
  1046.         return newEvent != null ? newEvent : mouseEvent;
  1047.     }
  1048.  
  1049.     void _convertMouseEventToMouseView(MouseEvent mouseEvent) {
  1050.         Point        mousePoint;
  1051.  
  1052.         if (_mouseView == null || mouseEvent == null) {
  1053.             return;
  1054.         }
  1055.  
  1056.         mousePoint = Point.newPoint();
  1057.         convertToView(_mouseView, mouseEvent.x, mouseEvent.y, mousePoint);
  1058.  
  1059.         mouseEvent.x = mousePoint.x;
  1060.         mouseEvent.y = mousePoint.y;
  1061.  
  1062.         Point.returnPoint(mousePoint);
  1063.     }
  1064.  
  1065.     /** Processes the various Events directed at the RootView.
  1066.       * You should never call this method.
  1067.       */
  1068.     public void processEvent(Event event) {
  1069.         MouseEvent      mouseEvent;
  1070.         int             type;
  1071.  
  1072.         /* If someone closes a window by calling dispose(), we may
  1073.          * have some event pending for a rootView that's no longer connected
  1074.          * to the application. When the rootView is removed, Application
  1075.          * call setApplet(null). This sets the application ivar to null.
  1076.          * if application is null, we should just ignore the event.
  1077.          */
  1078.         if (application == null)
  1079.             return;
  1080.  
  1081.         if (event instanceof MouseEvent) {
  1082.             mouseEvent = (MouseEvent)event;
  1083.             type = mouseEvent.type;
  1084.  
  1085.             if (type == MouseEvent.MOUSE_MOVED && mouseDownCount > 0 &&
  1086.                 _mouseView != null) {
  1087.                 /* something has gone wrong - we got a move with the
  1088.                  * mouse still down.  Pretend we got a mouse up at the
  1089.                  * last known point.
  1090.                  */
  1091.                 MouseEvent e = convertEventToView(_mouseView, mouseEvent);
  1092.                 e.setType(MouseEvent.MOUSE_UP);
  1093.                 _mouseUp(e);
  1094.             }
  1095.  
  1096.             if ((type == MouseEvent.MOUSE_DRAGGED) && _mouseView != null &&
  1097.                  _mouseView.wantsMouseEventCoalescing()) {
  1098.  
  1099.                 mouseEvent = removeMouseEvents(mouseEvent);
  1100.                 type = mouseEvent.type();
  1101.             } else if ((type == MouseEvent.MOUSE_MOVED) && _moveView != null &&
  1102.                  _moveView.wantsMouseEventCoalescing()) {
  1103.  
  1104.                 mouseEvent = removeMouseEvents(mouseEvent);
  1105.                 type = mouseEvent.type();
  1106.             }
  1107.  
  1108.             _mouseX = mouseEvent.x;
  1109.             _mouseY = mouseEvent.y;
  1110.  
  1111.             switch (type) {
  1112.                 case MouseEvent.MOUSE_DOWN:
  1113.                     /** Sometimes the awt forgets to tell us that
  1114.                      *  we are getting the focus. This is why we
  1115.                      *  need this hack
  1116.                      */
  1117.                     if(application.firstRootView() != this)
  1118.                         application.makeFirstRootView(this);
  1119.                     _mouseDown(mouseEvent);
  1120.                     break;
  1121.                 case MouseEvent.MOUSE_DRAGGED:
  1122.                     _convertMouseEventToMouseView(mouseEvent);
  1123.                     _mouseDrag(mouseEvent);
  1124.                     break;
  1125.                 case MouseEvent.MOUSE_UP:
  1126.                     _convertMouseEventToMouseView(mouseEvent);
  1127.                     _mouseUp(mouseEvent);
  1128.                     break;
  1129.                 case MouseEvent.MOUSE_ENTERED:
  1130.                     if (_mouseView == null) {
  1131.                         _mouseEnter(mouseEvent);
  1132.                     }
  1133.                     break;
  1134.                 case MouseEvent.MOUSE_MOVED:
  1135.                     _mouseMove(mouseEvent);
  1136.                     break;
  1137.                 case MouseEvent.MOUSE_EXITED:
  1138.                     if (_mouseView == null) {
  1139.                         _mouseExit(mouseEvent);
  1140.                     }
  1141.                     break;
  1142.             }
  1143.         } else if (event instanceof KeyEvent) {
  1144.             KeyEvent keyEvent = (KeyEvent) event;
  1145.             /** Sometimes the awt forgets to tell us that
  1146.              *  we are getting the focus. This is why we
  1147.              *  need this hack
  1148.              */
  1149.  
  1150.             if(application.firstRootView() != this)
  1151.                 application.makeFirstRootView(this);
  1152.             if (keyEvent.type == KeyEvent.KEY_DOWN)
  1153.                 _keyDown(keyEvent);
  1154.             else if(keyEvent.type == KeyEvent.KEY_UP)
  1155.                 _keyUp(keyEvent);
  1156.             else
  1157.                 _keyTyped(keyEvent);
  1158.         } else if (event instanceof ApplicationEvent) {
  1159.             ExternalWindow externalWindow = null;
  1160.  
  1161.             switch (event.type) {
  1162.                 case ApplicationEvent.GOT_FOCUS:
  1163.                     application.makeFirstRootView(this);
  1164.                     if (externalWindow != null) {
  1165.                         externalWindow.didBecomeMain();
  1166.                     }
  1167.                     if (_focusedView != null) {
  1168.                         _focusedView.resumeFocus();
  1169.                     }
  1170.                     break;
  1171.                 case ApplicationEvent.LOST_FOCUS:
  1172.                     externalWindow = externalWindow();
  1173.                     if (externalWindow != null) {
  1174.                         externalWindow.didResignMain();
  1175.                     }
  1176.                     if (_mainWindow != null) {
  1177.                         _setMainWindow(null);
  1178.                     }
  1179.                     if (_focusedView != null) {
  1180.                         _focusedView._pauseFocus();
  1181.                     }
  1182.                     break;
  1183.                 case ApplicationEvent.UPDATE:
  1184.                     //ALERT! Hack for the null graphics
  1185.                     if (isVisible) {
  1186.                         paint((ApplicationEvent)event);
  1187.                     }
  1188.                     break;
  1189.  
  1190.                 case ApplicationEvent.RESIZE:
  1191.                     /// ALERT fix for JDK 1.1.1 bug.
  1192.                     /// RESHAPE events are not followed by paint() events in 1.1.1.
  1193.                     /// Adding an extra UPDATE event to the EventLoop.
  1194.                     /// This only happens when the reshape is making the panel
  1195.                     /// smaller, going larger forces expose events that make us draw
  1196.                     /// properly. We will only add an event if we are being resized
  1197.                     /// smaller than our current size. This may cause an additional
  1198.                     /// paint to be called under 1.0.2, but the paint coalescing
  1199.                     /// should do it's job.
  1200.                     if(!bounds().equals(((ApplicationEvent)event).rect())
  1201.                         && bounds().contains(((ApplicationEvent)event).rect())) {
  1202.                         ApplicationEvent updateEvent = new ApplicationEvent();
  1203.                         updateEvent.data = ((ApplicationEvent)event).rect();
  1204.                         updateEvent.type = ApplicationEvent.UPDATE;
  1205.                         updateEvent.setProcessor(this);
  1206.                         if(application() != null && application().eventLoop() != null)
  1207.                             application().eventLoop().addEvent(updateEvent);
  1208.                     }
  1209.  
  1210.                     resize((ApplicationEvent)event);
  1211.                     /* There is no way to receive a notification when
  1212.                      * an external window get resized. This call to
  1213.                      * validateBounds() is a hack to give the external window
  1214.                      * a chance to call windowWillSizeBy() and to
  1215.                      * update its bounds
  1216.                      */
  1217.                     externalWindow = externalWindow();
  1218.                     if (externalWindow != null) {
  1219.                         externalWindow.validateBounds();
  1220.                     }
  1221.                     break;
  1222.                 case ApplicationEvent.APPLET_STARTED:
  1223.                     break;
  1224.                 case ApplicationEvent.PRINT:
  1225.                     print((ApplicationEvent)event);
  1226.                     break;
  1227.                 default:
  1228.             }
  1229.         }
  1230.     }
  1231.  
  1232.     void setFocusedView(View view, boolean hard) {
  1233.         View wasFocusedView;
  1234.  
  1235.         if (view != _focusedView) {
  1236.             if (_focusedView != null) {
  1237.                 wasFocusedView = _focusedView;
  1238.                 _focusedView = null;
  1239.                 if (hard) {
  1240.                     wasFocusedView._stopFocus();
  1241.                 } else {
  1242.                     wasFocusedView._pauseFocus();
  1243.                 }
  1244.             } else
  1245.                 _focusedView = null;
  1246.  
  1247.             if(_focusedView == null) {
  1248.                 _focusedView = view;
  1249.                 if (_focusedView != null) {
  1250.                     _focusedView._startFocus();
  1251.                 }
  1252.             }
  1253.             Application.application().focusChanged(_focusedView);
  1254.             Application.application().performCommandLater(this,
  1255.                                                           VALIDATE_SELECTED_VIEW,
  1256.                                                           null,true);
  1257.         }
  1258.     }
  1259.  
  1260.     /** Directs all key Events to <b>view</b>.
  1261.       */
  1262.     public void setFocusedView(View view) {
  1263.         setFocusedView(view, true);
  1264.     }
  1265.  
  1266.     /** Returns the View set to receive all key Events.
  1267.       * @see #setFocusedView
  1268.       */
  1269.     public View focusedView() {
  1270.         return _focusedView;
  1271.     }
  1272.  
  1273.     /** Implements the RootView's commands:
  1274.       * <ul>
  1275.       * <li>ExtendedTarget.SHOW_FONT_CHOOSER - makes the FontChooser visible.
  1276.       * <li>ExtendedTarget.SHOW_COLOR_CHOOSER - makes the ColorChooser visible.
  1277.       * <li>ExtendedTarget.NEW_FONT_SELECTION - causes the FontChooser to
  1278.       *                                         display the Font that is passed
  1279.       *                                         as the object.
  1280.       * </ul>
  1281.       */
  1282.     public void performCommand(String command, Object data) {
  1283.         if (SHOW_FONT_CHOOSER.equals(command)) {
  1284.             showFontChooser();
  1285.         } else if (SHOW_COLOR_CHOOSER.equals(command)) {
  1286.             showColorChooser();
  1287.         } else if (NEW_FONT_SELECTION.equals(command)) {
  1288.             if (fontChooser != null) {
  1289.                 fontChooser.setFont((Font)data);
  1290.             }
  1291.         } else if(VALIDATE_SELECTED_VIEW.equals(command)) {
  1292.             validateSelectedView();
  1293.         } else {
  1294.             throw new NoSuchMethodError("unknown command: " + command);
  1295.         }
  1296.     }
  1297.  
  1298.     /** Returns <b>true</b> for the commands that the RootView can perform.
  1299.       * @see #performCommand
  1300.       */
  1301.     public boolean canPerformCommand(String command) {
  1302.        return _commands.contains(command);
  1303.     }
  1304.  
  1305.     /** Sets the RootView's Color.
  1306.       */
  1307.     public void setColor(Color aColor) {
  1308.         _backgroundColor = aColor;
  1309.     }
  1310.  
  1311.     /** Returns the RootView's Color.
  1312.       * @see #setColor
  1313.       */
  1314.     public Color color() {
  1315.         return _backgroundColor;
  1316.     }
  1317.  
  1318.     /** Sets the RootView's Image.
  1319.       * @see #setImageDisplayStyle
  1320.       */
  1321.     public void setImage(Image anImage) {
  1322.         _image = anImage;
  1323.     }
  1324.  
  1325.     /** Returns the RootView's Image.
  1326.       * @see #setImage
  1327.       */
  1328.     public Image image() {
  1329.         return _image;
  1330.     }
  1331.  
  1332.     /** Sets the style the RootView uses to display its Image
  1333.       * (Image.CENTERED, Image.TILED, or Image.SCALED).
  1334.       */
  1335.     public void setImageDisplayStyle(int aStyle) {
  1336.         if (aStyle != Image.CENTERED && aStyle != Image.TILED &&
  1337.             aStyle != Image.SCALED) {
  1338.             throw new InconsistencyException("Unknown image display style: " +
  1339.                 aStyle);
  1340.         }
  1341.  
  1342.         _imageDisplayStyle = aStyle;
  1343.     }
  1344.  
  1345.     /** Returns the style the RootView uses to display its Image.
  1346.       * @see #setImageDisplayStyle
  1347.       */
  1348.     public int imageDisplayStyle() {
  1349.         return _imageDisplayStyle;
  1350.     }
  1351.  
  1352.     /** Returns <b>false</b> - RootViews are not transparent.
  1353.       */
  1354.     public boolean isTransparent() {
  1355.         return false;
  1356.     }
  1357.  
  1358.     /** Draws the RootView's contents.
  1359.       */
  1360.     public void drawView(Graphics g) {
  1361.         if (_image == null || (_imageDisplayStyle == Image.CENTERED &&
  1362.                             (_image.width() < bounds.width ||
  1363.                              _image.height() < bounds.height))) {
  1364.             if (_backgroundColor != null) {
  1365.                 g.setColor(_backgroundColor);
  1366.                 g.fillRect(g.clipRect());
  1367.             }
  1368.         }
  1369.  
  1370.         if (_image != null) {
  1371.             _image.drawWithStyle(g, 0, 0,
  1372.                                  bounds.width, bounds.height,
  1373.                                  _imageDisplayStyle);
  1374.         }
  1375.     }
  1376.  
  1377.     /** Overridden to draw just the <b>aRect</b> portion of the RootView,
  1378.       * ignoring any Windows that may intersect the Rect.  To draw everything
  1379.       * within a given Rect, call <b>redraw()</b>.
  1380.       * @see #redraw
  1381.       */
  1382.     public void draw(Graphics g, Rect aRect) {
  1383.         InternalWindow  nextWindow;
  1384.         Vector          enableVector;
  1385.         int             i;
  1386.  
  1387.         enableVector = new Vector();
  1388.  
  1389.         i = windows.count();
  1390.         while (i-- > 0) {
  1391.             nextWindow = (InternalWindow)windows.elementAt(i);
  1392.             if (nextWindow.isDrawingEnabled()) {
  1393.                 nextWindow.disableDrawing();
  1394.                 enableVector.addElement(nextWindow);
  1395.             }
  1396.         }
  1397.  
  1398.         super.draw(g, aRect);
  1399.  
  1400.         i = enableVector.count();
  1401.         while (i-- > 0) {
  1402.             nextWindow = (InternalWindow)enableVector.elementAt(i);
  1403.             nextWindow.reenableDrawing();
  1404.         }
  1405.     }
  1406.  
  1407.     // opaqueView is dead.  ALERT!
  1408.  
  1409.     View viewWithBuffer(View someView, Rect updateRect) {
  1410.         View    nextView, bufferView, opaqueView = null;
  1411.         int     i;
  1412.         Rect    subRect;
  1413.         Vector  views;
  1414.  
  1415.         i = someView.subviewCount();
  1416.         if (i == 0)
  1417.             return null;
  1418.  
  1419.         views = someView.subviews();
  1420.         subRect = Rect.newRect(0, 0, updateRect.width, updateRect.height);
  1421.  
  1422.         while (i-- > 0) {
  1423.             nextView = (View)views.elementAt(i);
  1424.  
  1425.             if (nextView instanceof InternalWindow ||
  1426.                 !nextView.bounds.contains(updateRect)) {
  1427.                 continue;
  1428.             }
  1429.  
  1430.             if (nextView.isBuffered()) {
  1431.                 Rect.returnRect(subRect);
  1432.                 return nextView;
  1433.             }
  1434.  
  1435.             if (!nextView.isTransparent()) {
  1436. //              opaqueView = nextView;
  1437.             }
  1438.  
  1439.             subRect.x = updateRect.x - nextView.bounds.x;
  1440.             subRect.y = updateRect.y - nextView.bounds.y;
  1441.             bufferView = viewWithBuffer(nextView, subRect);
  1442.             if (bufferView != null) {
  1443.                 Rect.returnRect(subRect);
  1444.                 return bufferView;
  1445.             }
  1446.             if (opaqueView != null) {
  1447.                 Rect.returnRect(subRect);
  1448.                 return opaqueView;
  1449.             }
  1450.         }
  1451.  
  1452.         Rect.returnRect(subRect);
  1453.  
  1454.         return null;
  1455.     }
  1456.  
  1457.     /** Similar to <b>draw()</b>, except that it draws everything intersecting
  1458.       * the Rect <b>aRect</b> (RootView and InternalWindows).
  1459.       */
  1460.     void redraw(Graphics g, Rect aRect) {
  1461.         InternalWindow  nextWindow;
  1462.         View            bufferView, viewForRect;
  1463.         Vector          intersectedWindows;
  1464.         int             i, count;
  1465.         boolean         foundWindow;
  1466.         Rect            subRect;
  1467.  
  1468.         subRect = Rect.newRect(0, 0, aRect.width, aRect.height);
  1469.  
  1470.         if (aRect == null) {
  1471.             aRect = new Rect(0, 0, bounds.width, bounds.height);
  1472.         }
  1473.  
  1474.         intersectedWindows = VectorCache.newVector();
  1475.  
  1476.         setRedrawTransparentWindows(false);
  1477.  
  1478.         /* which windows intersect aRect, and is there one that contains it? */
  1479.         count = windows.count();
  1480.         foundWindow = false;
  1481.         for (i = count; (i-- > 0) && !foundWindow; ) {
  1482.             /// ALERT FIX 1
  1483.             Rect windowBounds;
  1484.             nextWindow = (InternalWindow)windows.elementAt(i);
  1485.             windowBounds = absoluteWindowBounds(nextWindow);
  1486.             if (windowBounds.intersects(aRect)) {
  1487.                 intersectedWindows.addElement(nextWindow);
  1488.                 if (!nextWindow.isTransparent() &&
  1489.                     windowBounds.contains(aRect)) {
  1490.                     foundWindow = true;
  1491.                 }
  1492.             }
  1493.         }
  1494.  
  1495.         /* no window completely contains aRect, so find an opaque view that
  1496.          * does
  1497.          */
  1498.         if (!foundWindow) {
  1499.             viewForRect = _viewForRect(aRect, null);
  1500.  
  1501.             if (viewForRect != null) {
  1502.                 convertRectToView(viewForRect, aRect, subRect);
  1503.                 g.pushState();
  1504.                 g.translate(aRect.x - subRect.x, aRect.y - subRect.y);
  1505.                 viewForRect.draw(g, subRect);
  1506.                 g.popState();
  1507.             } else {
  1508.                 draw(g, aRect);
  1509.             }
  1510.         }
  1511.  
  1512.         count = intersectedWindows.count();
  1513.         for (i = 0; i < count; i++) {
  1514.             View windowSuperview;
  1515.  
  1516.             nextWindow = (InternalWindow)intersectedWindows.elementAt(i);
  1517.  
  1518.             windowSuperview = nextWindow.superview();
  1519.             convertRectToView(windowSuperview, aRect, subRect);
  1520.             viewForRect = nextWindow._viewForRect(subRect, windowSuperview);
  1521.             if (viewForRect == null) {
  1522.                 viewForRect = nextWindow;
  1523.             }
  1524.             convertRectToView(viewForRect, aRect, subRect);
  1525.  
  1526.             g.pushState();
  1527.             g.translate(aRect.x - subRect.x, aRect.y - subRect.y);
  1528.             viewForRect.draw(g, subRect);
  1529.             g.popState();
  1530.         }
  1531.  
  1532.         setRedrawTransparentWindows(true);
  1533.         Rect.returnRect(subRect);
  1534.         VectorCache.returnVector(intersectedWindows);
  1535.     }
  1536.  
  1537.     /** Similar to <b>draw()</b>, except that it draws everything intersecting
  1538.       * the Rect <b>aRect</b> (RootView and InternalWindows).
  1539.       */
  1540.     public void redraw(Rect aRect) {
  1541.         Graphics graphics = createGraphics();
  1542.  
  1543.         redraw(graphics, aRect);
  1544.         graphics.dispose();
  1545.     }
  1546.  
  1547.     /** Convenience method for drawing the entire RootView.  Equivalent
  1548.       * to the following code:
  1549.       * <pre>
  1550.       *     redraw(new Graphics(rootView()), null);
  1551.       * </pre>
  1552.       */
  1553.     void redraw() {
  1554.         Graphics graphics = createGraphics();
  1555.         Rect    tmpRect;
  1556.  
  1557.         tmpRect = Rect.newRect(0, 0, bounds.width, bounds.height);
  1558.         redraw(graphics, tmpRect);
  1559.         Rect.returnRect(tmpRect);
  1560.  
  1561.         graphics.dispose();
  1562.     }
  1563.  
  1564.     /** View calls this method when it goes from not dirty to dirty.
  1565.       */
  1566.     synchronized void markDirty(View dirtyView) {
  1567.         // Add the view to the list of views of dirtyViews.  If we are
  1568.         // currently processing dirtyViews then dirtyViews will be set to
  1569.         // null.  Nobody should mark themselves dirty while drawing.
  1570.  
  1571.         if (dirtyViews != null) {
  1572.             dirtyViews.addElement(dirtyView);
  1573.         } else {
  1574.             throw new InconsistencyException("Don't dirty a View while the list of dirty views is being drawn!");
  1575.         }
  1576.     }
  1577.  
  1578.     /** View calls this method when it goes from dirty to not dirty.
  1579.       */
  1580.     synchronized void markClean(View dirtyView) {
  1581.         // If a view becomes clean, remove it from the dirtyViews Vector.  If
  1582.         // dirtyViews is null then we are in the process of cleaning the
  1583.         // dirtyViews so we can just ignore the request since the vector is
  1584.         // about to be emptied anyway.
  1585.  
  1586.         if (dirtyViews != null)
  1587.             dirtyViews.removeElement(dirtyView);
  1588.     }
  1589.  
  1590.     /** Marks all of the RootView's dirty subviews as clean, without
  1591.       * drawing them.
  1592.       */
  1593.     public synchronized void resetDirtyViews() {
  1594.         int i, count;
  1595.         View dirtyView;
  1596.         Vector tmpDirtyViews;
  1597.  
  1598.         tmpDirtyViews = dirtyViews;
  1599.         dirtyViews = null;
  1600.  
  1601.         count = tmpDirtyViews.count();
  1602.         for (i = 0; i < count; i++) {
  1603.             dirtyView = (View)tmpDirtyViews.elementAt(i);
  1604.             dirtyView.setDirty(false);
  1605.         }
  1606.  
  1607.         tmpDirtyViews.removeAllElements();
  1608.         dirtyViews = tmpDirtyViews;
  1609.     }
  1610.  
  1611.     /** Draws all of the RootView's dirty subviews. This method
  1612.       * is called automatically after the EventLoop processes an Event.
  1613.       */
  1614.     public synchronized void drawDirtyViews() {
  1615.         int i, count;
  1616.         Rect tmp;
  1617.         Vector roots, tmpDirtyViews;
  1618.         View dirtyView;
  1619.  
  1620.         count = dirtyViews.count();
  1621.         if (count == 0)
  1622.             return;
  1623.  
  1624.         // While we are processing the vector of dirty views, move it aside
  1625.         // so that it can't be mucked with by errant views.  The method
  1626.         // markDirty() will throw an exception if someone tries to mark a view
  1627.         // dirty while we are processing the list.
  1628.  
  1629.         tmpDirtyViews = dirtyViews;
  1630.  
  1631.         try {
  1632.             dirtyViews = null;
  1633.  
  1634.             roots = new Vector(count);
  1635.             tmp = new Rect();
  1636.  
  1637.             for (i = 0; i < count; i++) {
  1638.                 dirtyView = (View)tmpDirtyViews.elementAt(i);
  1639.                 collectDirtyViews(dirtyView, roots, tmp);
  1640.             }
  1641.  
  1642.             count = roots.count();
  1643.             for (i = 0; i < count; i++) {
  1644.                 dirtyView = (View)roots.elementAt(i);
  1645.                 dirtyView.draw(dirtyView.dirtyRect);
  1646.             }
  1647.         } finally {
  1648.             dirtyViews = tmpDirtyViews;
  1649.             resetDirtyViews();
  1650.         }
  1651.     }
  1652.  
  1653.     void collectDirtyViews(View dirtyView, Vector roots, Rect tmp) {
  1654.         int dx, dy, rootDx, rootDy;
  1655.         View view, rootDirtyView;
  1656.  
  1657.         // Find the highest superview which is dirty.  When we get out of this
  1658.         // rootDx and rootDy will contain the translation from the
  1659.         // rootDirtyView's coordinate system to the coordinates of the
  1660.         // original dirtyView.  The tmp Rect is also used to compute the
  1661.         // visible portion of the dirtyRect.
  1662.  
  1663.         view = rootDirtyView = dirtyView;
  1664.         dx = rootDx = 0;
  1665.         dy = rootDy = 0;
  1666.         tmp.setBounds(0, 0, view.width(), view.height());
  1667.  
  1668.         // If the dirtyRect is null, then the whole View is dirty.
  1669.  
  1670.         // If this can be done last, it might optimize some special cases.
  1671.         // ALERT!
  1672.         if (dirtyView.dirtyRect != null)
  1673.             tmp.intersectWith(dirtyView.dirtyRect);
  1674.  
  1675.         if (tmp.isEmpty())
  1676.             return;
  1677.  
  1678.         do {
  1679.             dx += view.bounds.x;
  1680.             dy += view.bounds.y;
  1681.             tmp.moveBy(view.bounds.x, view.bounds.y);
  1682.  
  1683.             view = view.superview();
  1684.  
  1685.             if (view != null) {
  1686.                 tmp.intersectWith(0, 0, view.width(), view.height());
  1687.                 if (tmp.isEmpty())
  1688.                     return;
  1689.  
  1690.                 if (view.isDirty()) {
  1691.                     rootDirtyView = view;
  1692.                     rootDx = dx;
  1693.                     rootDy = dy;
  1694.                 }
  1695.             }
  1696.         } while (view != null && !(view instanceof InternalWindow));
  1697.  
  1698.         // At this point the visible portion of the dirtyRect is in the
  1699.         // RootView's coordinate system.  Put it in the coordinate
  1700.         // system of the rootDirtyView.  Also add the dirtyRect of the
  1701.         // dirtyView to the rootDirtyView.
  1702.  
  1703.         if (dirtyView != rootDirtyView) {
  1704.             tmp.moveBy(rootDx - dx, rootDy - dy);
  1705.             rootDirtyView.addDirtyRect(tmp);
  1706.         }
  1707.  
  1708.         // If we haven't seen this root before, then we need to add it to the
  1709.         // list of root dirty Views.
  1710.  
  1711.         if (!roots.containsIdentical(rootDirtyView))
  1712.             roots.addElement(rootDirtyView);
  1713.     }
  1714.  
  1715.     /** Overridden to prevent mouse Events from being sent to the
  1716.       * RootView. Returns <b>false</b>.
  1717.       */
  1718.     public boolean mouseDown(MouseEvent event) {
  1719.         return false;
  1720.     }
  1721.  
  1722.     /** Overridden to return this View.
  1723.       */
  1724.     public RootView rootView() {
  1725.         if (panel == null)
  1726.             return super.rootView();
  1727.         else
  1728.             return this;
  1729.     }
  1730.  
  1731.     void setPanel(FoundationPanel p) {
  1732.         panel = p;
  1733.     }
  1734.  
  1735.     /** Returns the FoundationPanel the RootView is being displayed in. */
  1736.     public FoundationPanel panel() {
  1737.         return panel;
  1738.     }
  1739.  
  1740.     /** Returns the Application that owns the RootView.
  1741.       */
  1742.     Application application() {
  1743.         return application;
  1744.     }
  1745.  
  1746.     void setApplication(Application a) {
  1747.         application = a;
  1748.     }
  1749.  
  1750.     /** @private
  1751.       */
  1752.     public void setWindowClipView(View aView) {
  1753.         _windowClipView = aView;
  1754.     }
  1755.  
  1756.     /** @private
  1757.       */
  1758.     public View windowClipView() {
  1759.         return _windowClipView;
  1760.     }
  1761.  
  1762.     void addComponentView(AWTComponentView componentView) {
  1763.         if (componentViews == null) {
  1764.             componentViews = new Vector();
  1765.         }
  1766.  
  1767.         componentViews.addElement(componentView);
  1768.         componentView.setComponentBounds();
  1769.         panel.add(componentView.component);
  1770.     }
  1771.  
  1772.     void removeComponentView(AWTComponentView componentView) {
  1773.         if (componentViews == null) {
  1774.             componentViews = new Vector();
  1775.         }
  1776.  
  1777.         componentViews.removeElement(componentView);
  1778.         panel.remove(componentView.component);
  1779.     }
  1780.  
  1781.     private final void subviewDidResizeOrMove(View aView) {
  1782.         AWTComponentView        view;
  1783.         int                     count, i;
  1784.  
  1785.         if (componentViews != null) {
  1786.             count = componentViews.count();
  1787.  
  1788.             for (i = 0; i < count; i++) {
  1789.                view = (AWTComponentView)componentViews.elementAt(i);
  1790.  
  1791.                 if (view.descendsFrom(aView)) {
  1792.                     view.setComponentBounds();
  1793.                 }
  1794.             }
  1795.         }
  1796.  
  1797.         createMouseEnterLater();
  1798.         if(application!=null) {
  1799.             KeyboardArrow arrow = application.keyboardArrow();
  1800.             View v = arrow.view();
  1801.             if(v != null && v.rootView() == this) {
  1802.                 updateArrowLocation(arrow);
  1803.             }
  1804.         }
  1805.     }
  1806.  
  1807.     /** @private
  1808.       */
  1809.     public void subviewDidResize(View aView) {
  1810.         subviewDidResizeOrMove(aView);
  1811.     }
  1812.  
  1813.     /** @private
  1814.       */
  1815.     public void subviewDidMove(View aView) {
  1816.         subviewDidResizeOrMove(aView);
  1817.     }
  1818.  
  1819.     /** @private
  1820.       */
  1821.     public boolean canDraw() {
  1822.         if (panel.getParent() == null)
  1823.             return false;
  1824.         else
  1825.             return isVisible;
  1826.     }
  1827.  
  1828.     /** Returns a newly-allocated Point containing the mouse's last known
  1829.       * location, in the RootView's coordinate system.
  1830.       */
  1831.     public Point mousePoint() {
  1832.         return new Point(_mouseX, _mouseY);
  1833.     }
  1834.  
  1835.  
  1836.     /** This method determines if <b>aView</b> should not get events
  1837.       * while there is a modal session in progress. If this method returns
  1838.       * false, then <b>aView</b> is allowed to get events. The current
  1839.       * implementation confirms that <b>aView</b> is a subview of the current
  1840.       * modal view and returns true. You can override this method if you want
  1841.       * to extend the allowed views to include views
  1842.       * other than those in the modal view.
  1843.       */
  1844.     public boolean viewExcludedFromModalSession(View aView ) {
  1845.         View modalView;
  1846.  
  1847.         if(aView == null)
  1848.             return true;
  1849.  
  1850.         modalView = Application.application().modalView();
  1851.         if( modalView != null && !aView.descendsFrom(modalView)) {
  1852.             if(aView instanceof DragView || aView instanceof InternalWindow)
  1853.                 return false;
  1854.             else
  1855.                 return true;
  1856.         } else
  1857.             return false;
  1858.     }
  1859.  
  1860.     /** @private */
  1861.     public void setRedrawAll(boolean flag) {
  1862.         redrawAll = flag;
  1863.     }
  1864.  
  1865.     /** @private */
  1866.     public boolean redrawAll() {
  1867.         return redrawAll;
  1868.     }
  1869.  
  1870.     Rect absoluteWindowBounds(InternalWindow window)    {
  1871.         if(window.superview() != this)
  1872.             return window.superview().convertRectToView(this, window.bounds);
  1873.         return window.bounds;
  1874.     }
  1875.  
  1876.     void viewHierarchyChanged(){
  1877.         if(_focusedView != null && !_focusedView.descendsFrom(this))
  1878.             setFocusedView(null);
  1879.  
  1880.         Application.application().performCommandLater(this,VALIDATE_SELECTED_VIEW,null,true);
  1881.     }
  1882.  
  1883.     private boolean isInWindow(View aView) {
  1884.       View superview;
  1885.  
  1886.       if(aView == null)
  1887.           return false;
  1888.       else if(aView instanceof InternalWindow)
  1889.           return true;
  1890.       else {
  1891.           superview = aView.superview();
  1892.           do {
  1893.               if(superview == this)
  1894.                   return false;
  1895.               else if(superview instanceof InternalWindow)
  1896.                   return true;
  1897.               superview = superview.superview();
  1898.           } while(superview != null);
  1899.       }
  1900.       return false;
  1901.     }
  1902.  
  1903.     /** Return true if the root view as received a mouse down and
  1904.      *  is waiting for a mouse up
  1905.      * @private
  1906.      */
  1907.     public boolean mouseStillDown() {
  1908.         if(mouseDownCount > 0)
  1909.             return true;
  1910.         else
  1911.             return false;
  1912.     }
  1913.  
  1914.     View rootViewFocusedView() {
  1915.         if(_rootViewFocusedView != null) {
  1916.             if(_rootViewFocusedView.descendsFrom(this))
  1917.                 return _rootViewFocusedView;
  1918.             else
  1919.                 _rootViewFocusedView = null;
  1920.         }
  1921.         return null;
  1922.     }
  1923.  
  1924.  
  1925.     /*** Selected view for keyboard UI ****/
  1926.  
  1927.     /** Set the default selected view
  1928.       *
  1929.       */
  1930.     public void setDefaultSelectedView(View aView) {
  1931.         _defaultSelectedView = aView;
  1932.     }
  1933.  
  1934.     /** Returns the default selected view
  1935.       *
  1936.       */
  1937.     public View defaultSelectedView() {
  1938.         return _defaultSelectedView;
  1939.     }
  1940.  
  1941.     /** Ask the receiving RootView to make <b>newSelectedView</b>
  1942.       * the selected view for keyboard UI. If <b>changeFocus</b>
  1943.       * is true, the rootview will abort any editing to select
  1944.       * the view. This method does nothing if keyboard UI is not
  1945.       * active.
  1946.       *
  1947.       */
  1948.     public void selectView(View newSelectedView,boolean abortCurrentEditing) {
  1949.         View kbdRoot = keyboardRootView();
  1950.  
  1951.         if((application != null && !application.isKeyboardUIEnabled()) ||
  1952.            _selectedView == kbdRoot || _selectedView == null)
  1953.             return;
  1954.  
  1955.         if(abortCurrentEditing)
  1956.             setFocusedView(null);
  1957.  
  1958.         if(_focusedView == null &&
  1959.            newSelectedView.canBecomeSelectedView() &&
  1960.            newSelectedView.descendsFrom(kbdRoot)) {
  1961.             View superview = newSelectedView.superview();
  1962.             if(superview != kbdRoot) {
  1963.                 do {
  1964.                     if(superview.hidesSubviewsFromKeyboard())
  1965.                         newSelectedView = superview;
  1966.                     superview = superview.superview();
  1967.                 } while(superview != kbdRoot);
  1968.             }
  1969.             makeSelectedView(newSelectedView);
  1970.         } else {
  1971.             if(kbdRoot instanceof RootView)
  1972.                 ((RootView)kbdRoot).setDefaultSelectedView(newSelectedView);
  1973.             else if(kbdRoot instanceof InternalWindow)
  1974.                 ((InternalWindow)kbdRoot).setDefaultSelectedView(newSelectedView);
  1975.         }
  1976.     }
  1977.  
  1978.     /** Ask the receiving RootView to make the view following <b>aView</b>
  1979.       * to become selected.
  1980.       *
  1981.       */
  1982.     public void selectViewAfter(View aView) {
  1983.         View nextSelectedView = null;
  1984.         nextSelectedView = findNextView(aView,keyboardRootView(),true);
  1985.         makeSelectedView(nextSelectedView);
  1986.     }
  1987.  
  1988.     /** Ask the receiving RootView to make the view before <b>aView</b>
  1989.       * to become selected.
  1990.       *
  1991.       */
  1992.     public void selectViewBefore(View aView) {
  1993.         View nextSelectedView = null;
  1994.         nextSelectedView = findNextView(aView,keyboardRootView(),false);
  1995.         makeSelectedView(nextSelectedView);
  1996.     }
  1997.  
  1998.     void didBecomeFirstRootView() {
  1999.         ExternalWindow externalWindow = externalWindow();
  2000.  
  2001.         if (externalWindow != null) {
  2002.             externalWindow.didBecomeMain();
  2003.         }
  2004.         if (_focusedView != null) {
  2005.             _focusedView._startFocus();
  2006.             Application.application().focusChanged(_focusedView);
  2007.         }
  2008.         application.performCommandLater(this,VALIDATE_SELECTED_VIEW, null,true);
  2009.     }
  2010.  
  2011.     void didResignFirstRootView() {
  2012.         ExternalWindow externalWindow = externalWindow();
  2013.  
  2014.  
  2015.         if (externalWindow != null) {
  2016.             externalWindow.didResignMain();
  2017.         }
  2018.         if (_mainWindow != null) {
  2019.             _setMainWindow(null);
  2020.         }
  2021.         if (_focusedView != null) {
  2022.             _focusedView._pauseFocus();
  2023.         }
  2024.         application.performCommandLater(this,VALIDATE_SELECTED_VIEW, null,true);
  2025.     }
  2026.  
  2027.     void makeSelectedView(View nextSelectedView) {
  2028.         if(application != null && application.isKeyboardUIEnabled()) {
  2029.             View keyboardRootView = keyboardRootView();
  2030.             if(nextSelectedView != _selectedView) {
  2031.                 if(_selectedView!=null) {
  2032.                     _selectedView.willBecomeUnselected();
  2033.                     _selectedView = null;
  2034.                 }
  2035.  
  2036.                 _selectedView = nextSelectedView;
  2037.  
  2038.                 if(_selectedView != null) {
  2039.                     if(keyboardRootView instanceof RootView)
  2040.                         ((RootView)keyboardRootView).setDefaultSelectedView(_selectedView);
  2041.                     else if(keyboardRootView instanceof InternalWindow)
  2042.                         ((InternalWindow)keyboardRootView).setDefaultSelectedView(_selectedView);
  2043.  
  2044.                     _selectedView.scrollRectToVisible(new Rect(0,0,
  2045.                                                                _selectedView.width(),
  2046.                                                                _selectedView.height()));
  2047.                     _selectedView.willBecomeSelected();
  2048.                 }
  2049.                 validateKeyboardArrow();
  2050.             }
  2051.         }
  2052.     }
  2053.  
  2054.     void validateKeyboardArrow() {
  2055.         if(application != null && application.isKeyboardUIEnabled()) {
  2056.             View needArrowView = null;
  2057.             if(_selectedView != null && _selectedView.wantsKeyboardArrow())
  2058.                 needArrowView = _selectedView;
  2059.             else if(_focusedView != null && _focusedView.canBecomeSelectedView() &&
  2060.                     _focusedView.wantsKeyboardArrow())
  2061.                 needArrowView = _focusedView;
  2062.             else
  2063.                 needArrowView = null;
  2064.  
  2065.             if(needArrowView != null)
  2066.                 showKeyboardArrowForView(needArrowView);
  2067.             else
  2068.                 hideKeyboardArrow();
  2069.         }
  2070.     }
  2071.  
  2072.     void validateSelectedView() {
  2073.         if(application != null && !application.isKeyboardUIEnabled())
  2074.             return;
  2075.  
  2076.         if(_focusedView != null
  2077.             || (application != null && application.firstRootView() != this)) {
  2078.             if(_selectedView != null) {
  2079.                 makeSelectedView(null);
  2080.             }
  2081.         } else {
  2082.             View kbdRoot = keyboardRootView();
  2083.             View defaultView;
  2084.  
  2085.             if(_selectedView != null && _selectedView.descendsFrom(kbdRoot)) {
  2086.                 boolean opaqueNodeFound = false;
  2087.  
  2088.                 /** if selected view is InternalWindow or RootView, it means that kbd UI was not
  2089.                  *  previously active. We should select the default selected view of the next
  2090.                  *  keyboard root view if kbd root view is different
  2091.                  */
  2092.                 if(!((_selectedView instanceof InternalWindow ||
  2093.                       _selectedView instanceof RootView) && _selectedView != kbdRoot)) {
  2094.                     if(_selectedView != kbdRoot) {
  2095.                         View superview = _selectedView.superview();
  2096.  
  2097.                         while(superview != null && superview != kbdRoot) {
  2098.                             if(superview.hidesSubviewsFromKeyboard()) {
  2099.                                 opaqueNodeFound = true;
  2100.                                 break;
  2101.                             }
  2102.                             superview = superview.superview();
  2103.                         }
  2104.                     }
  2105.                     if(!opaqueNodeFound)
  2106.                         return;
  2107.                     else
  2108.                         makeSelectedView(null);
  2109.                 }
  2110.             }
  2111.  
  2112.             if(kbdRoot instanceof RootView)
  2113.                 defaultView = ((RootView)kbdRoot).defaultSelectedView();
  2114.             else if(kbdRoot instanceof InternalWindow)
  2115.                 defaultView = ((InternalWindow)kbdRoot).defaultSelectedView();
  2116.             else
  2117.                 defaultView = null;
  2118.  
  2119.             if(defaultView != null && defaultView.descendsFrom(kbdRoot)) {
  2120.                 makeSelectedView(defaultView);
  2121.             } else {
  2122.                 selectNextSelectableView();
  2123.             }
  2124.         }
  2125.         validateKeyboardArrow();
  2126.     }
  2127.  
  2128.     /** Select the next available view for the keyboard UI **/
  2129.     void selectNextSelectableView() {
  2130.         View kbdRoot = keyboardRootView();
  2131.         View nextSelectedView = null;
  2132.  
  2133.         if(_selectedView != null && _selectedView.descendsFrom(kbdRoot))
  2134.             nextSelectedView = findNextView(_selectedView,kbdRoot,true);
  2135.         else
  2136.             nextSelectedView = findNextView(null,kbdRoot,true);
  2137.  
  2138.         makeSelectedView(nextSelectedView);
  2139.     }
  2140.  
  2141.     /** Select the previous available view for the keyboard UI **/
  2142.     void selectPreviousSelectableView() {
  2143.         View kbdRoot = keyboardRootView();
  2144.         View nextSelectedView = null;
  2145.         if(_selectedView != null && _selectedView.descendsFrom(kbdRoot))
  2146.             nextSelectedView = findNextView(_selectedView,kbdRoot,false);
  2147.         else
  2148.             nextSelectedView = findNextView(null,kbdRoot,false);
  2149.         makeSelectedView(nextSelectedView);
  2150.     }
  2151.  
  2152.     boolean processKeyboardEvent(KeyEvent anEvent,boolean commandModifierOnly) {
  2153.         View nextSelectedView;
  2154.         View view;
  2155.         View kbdRoot;
  2156.         KeyStroke ks;
  2157.  
  2158.         if((application != null && application.isKeyboardUIEnabled() == false)
  2159.                                   || subviews().count() == 0)
  2160.             return false;
  2161.  
  2162.         if(commandModifierOnly && !anEvent.isControlKeyDown())
  2163.             return false;
  2164.  
  2165.         if(!commandModifierOnly && anEvent.isControlKeyDown())
  2166.             return false;
  2167.  
  2168.         kbdRoot = keyboardRootView();
  2169.         validateSelectedView();
  2170.  
  2171.         if(!commandModifierOnly) {
  2172.             if(anEvent.isTabKey() || anEvent.isBackTabKey()) {
  2173.                 if(anEvent.isBackTabKey())
  2174.                     selectPreviousSelectableView();
  2175.                 else
  2176.                     selectNextSelectableView();
  2177.                 return true;
  2178.             }
  2179.         }
  2180.  
  2181.         ks = new KeyStroke(anEvent);
  2182.  
  2183.         /** Try to send the key stroke to the selected widget **/
  2184.         if(_selectedView != null) {
  2185.             if(_selectedView.performCommandForKeyStroke(ks,View.WHEN_SELECTED)) {
  2186.                 return true;
  2187.             }
  2188.  
  2189.             /** All the views from the selectedView to the keyboard root view **/
  2190.             if(_selectedView != kbdRoot) {
  2191.                 view = _selectedView.superview();
  2192.                 while(view != kbdRoot) {
  2193.                     if(view.performCommandForKeyStroke(ks,View.WHEN_IN_MAIN_WINDOW)) {
  2194.                         return true;
  2195.                     }
  2196.                     view = view.superview();
  2197.                 }
  2198.             }
  2199.         }
  2200.  
  2201.         /** All the other views from kbdRoot **/
  2202.         view = kbdRoot;
  2203.         do {
  2204.             view = nextView(view,kbdRoot,true,true,false);
  2205.             if(view.performCommandForKeyStroke(ks,View.WHEN_IN_MAIN_WINDOW)) {
  2206.                 return true;
  2207.             }
  2208.         } while(view != kbdRoot);
  2209.  
  2210.         /** All the other views.***/
  2211.         view = this;
  2212.         do {
  2213.             view = nextView(view,this,true,true,true);
  2214.             if(view.performCommandForKeyStroke(ks,View.ALWAYS)) {
  2215.                 return true;
  2216.             }
  2217.         } while(view != this);
  2218.  
  2219.         return false;
  2220.     }
  2221.  
  2222.    private View nextView(View view,View root,boolean canGoDown,boolean moveForward,
  2223.                         boolean includingInternalWindows) {
  2224.         View nsv = null;
  2225.         if(view == root && canGoDown) {
  2226.             Vector sub = root.subviews();
  2227.             if(sub.count() > 0) {
  2228.                 if(moveForward)
  2229.                     return root.firstSubview();
  2230.                 else
  2231.                     return root.lastSubview();
  2232.             } else
  2233.                 return null;
  2234.         } else {
  2235.             if(canGoDown &&
  2236.                (!view.hidesSubviewsFromKeyboard() ||
  2237.                 (includingInternalWindows && view instanceof InternalWindow)) &&
  2238.                view.subviews().count() > 0) {
  2239.                 if(moveForward)
  2240.                     return view.firstSubview();
  2241.                 else
  2242.                     return view.lastSubview();
  2243.             } else {
  2244.                 View superView = view.superview();
  2245.                 if(moveForward) {
  2246.                     nsv = superView.viewAfter(view);
  2247.                     if(nsv != null)
  2248.                         return nsv;
  2249.                 } else {
  2250.                     nsv = superView.viewBefore(view);
  2251.                     if(nsv != null)
  2252.                         return nsv;
  2253.                 }
  2254.                 if(superView == root)
  2255.                     return root;
  2256.                 else
  2257.                     return nextView(superView,root,false,moveForward,includingInternalWindows);
  2258.             }
  2259.         }
  2260.     }
  2261.  
  2262.     private View findNextView(View selectedView,View root,boolean moveForward) {
  2263.         View nextView;
  2264.         View initialView;
  2265.  
  2266.         if(root==null)
  2267.             return null;
  2268.  
  2269.  
  2270.         if(selectedView == null) {
  2271.             return root;
  2272.         }
  2273.  
  2274.         nextView = initialView = selectedView;
  2275.         do {
  2276.             nextView = nextView(nextView,root,true,moveForward,false);
  2277.             if(nextView == null)
  2278.                 break;
  2279.             if(nextView == initialView)
  2280.                 break;
  2281.         } while(!(nextView.canBecomeSelectedView()));
  2282.  
  2283.         return nextView;
  2284.     }
  2285.  
  2286.     private View keyboardRootView() {
  2287.         View modalView = Application.application().modalView();
  2288.         if(modalView != null && modalView.isInViewHierarchy()) {
  2289.             return modalView;
  2290.         } else {
  2291.             Window mainWindow = mainWindow();
  2292.             if(mainWindow != null) {
  2293.                 return (View)mainWindow;
  2294.             } else {
  2295.                 if(application != null && application.firstRootView() != null)
  2296.                     return application.firstRootView();
  2297.                 else
  2298.                     return this;
  2299.             }
  2300.         }
  2301.     }
  2302.  
  2303.     void showKeyboardArrowForView(View aView) {
  2304.         if(application!=null){
  2305.             KeyboardArrow  arrow = application.keyboardArrow();
  2306.             if(arrow.view() == aView)
  2307.                 return;
  2308.             else {
  2309.                 arrow.setRootView(this);
  2310.                 arrow.setView(aView);
  2311.                 updateArrowLocation(arrow);
  2312.                 arrow.show();
  2313.             }
  2314.         }
  2315.     }
  2316.  
  2317.     void updateArrowLocation(KeyboardArrow arrow) {
  2318.         View aView = arrow.view();
  2319.         int        position  = application.keyboardArrowPosition(aView);
  2320.         Image     arrowImage =  application.keyboardArrowImage(position);
  2321.         Point     arrowHotSpot= application.keyboardArrowHotSpot(position);
  2322.         Point     arrowLocation = application.keyboardArrowLocation(aView,position);
  2323.  
  2324.         arrowLocation.x -= arrowHotSpot.x;
  2325.         arrowLocation.y -= arrowHotSpot.y;
  2326.  
  2327.         if(windowClipView() != null) {
  2328.             convertPointToView(windowClipView(),arrowLocation,arrowLocation);
  2329.         }
  2330.         arrow.setImage(arrowImage);
  2331.         arrow.moveTo(arrowLocation.x,
  2332.                      arrowLocation.y);
  2333.     }
  2334.  
  2335.     void hideKeyboardArrow() {
  2336.         if(application!=null){
  2337.             KeyboardArrow arrow = application.keyboardArrow();
  2338.  
  2339.             if(arrow.rootView() == this) {
  2340.                 arrow.hide();
  2341.                 arrow.setRootView(null);
  2342.                 arrow.setView(null);
  2343.             }
  2344.         }
  2345.     }
  2346.  
  2347.     public boolean canBecomeSelectedView() {
  2348.         return true;
  2349.     }
  2350.  
  2351.     boolean wantsKeyboardArrow() {
  2352.         return false;
  2353.     }
  2354.  
  2355.     /** @private
  2356.       */
  2357.     public void adjustForExpectedMouseDownCount()
  2358.     {
  2359.         if(!application.jdkMouseEventHackEnabled)
  2360.             return;
  2361.         if (mouseDownCount < 1) {
  2362.             // This shouldn't happen
  2363.             MouseEvent me = new MouseEvent(0, MouseEvent.MOUSE_DOWN, -1, -1, 0);
  2364.             while (mouseDownCount < 1) {
  2365.                 _mouseDown(me);
  2366.             }
  2367.         } else if (mouseDownCount > 1) {
  2368.             // This shouldn't happen
  2369.             // Do nothing
  2370.         } else {
  2371.             // This shouldn't happen
  2372.             // Do nothing
  2373.         }
  2374.     }
  2375. }
  2376.